﻿using log4net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MyWebApp.Common.UIAttribute
{
    public class CustHandleErrorAttribute : HandleErrorAttribute
    {
        private static ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        public override void OnException(ExceptionContext filterContext)
        {
            //只能处理500错误
            if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
            {
                return;
            }
            //如果是AJAX请求返回json
            if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
            {
                filterContext.Result = new JsonResult()
                {
                    JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                    Data = new
                    {
                        error = true,
                        message = filterContext.Exception.Message
                    }
                };
            }
            else
            {
                var controllerName = (string)filterContext.RouteData.Values["controller"];
                var actionName = (string)filterContext.RouteData.Values["action"];
                var model = new MyHandleErrorInfo(filterContext.Exception, controllerName, actionName);
                model.ErrorType = filterContext.Exception.GetType().Name;
                model.ErrorName = model.ErrorType == "SessionTimeoutException" ? "登录超时" : "内部错误";
                filterContext.Result = new ViewResult()
                {
                    ViewName = View,
                    MasterName = Master,
                    ViewData = new ViewDataDictionary(model),
                    TempData = filterContext.Controller.TempData
                };

                //重定向方式
                //string url = new UrlHelper(filterContext.RequestContext).Action("Error", "ErrorHandle",
                //    new RouteValueDictionary(new ErrorModel()
                //    {
                //        ControllerName = controllerName,
                //        ActionName = actionName,
                //        ExceptionInfo = filterContext.Exception
                //    }));
                //filterContext.HttpContext.Response.Redirect(url);

                //日志记录
                if (model.ErrorType == "SessionTimeoutException")
                {
                    log.WarnFormat("{0}-{1}登录超时", controllerName, actionName);
                }
                else
                {
                    log.Error(string.Format("{0}-{1}执行出错", controllerName, actionName), filterContext.Exception);
                }
                
            }

            filterContext.ExceptionHandled = true;
            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.StatusCode = 500;
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;

            //base.OnException(filterContext);
        }
    }

    public class MyHandleErrorInfo : HandleErrorInfo
    {
        public MyHandleErrorInfo(Exception exception, string controllerName, string actionName)
            : base(exception, controllerName, actionName) { }

        public string ErrorType { get; set; }
        public string ErrorName { get; set; }
    }
}